package com.kylin.common.qrcode;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;

import org.iherus.codegen.qrcode.*;

/**
 * 带文字二维码生成类
 * 更多普通二维码生成参考：https://gitee.com/iherus/qrext4j
 *
 * @author wuhao
 * @version 1.0 - 2020/3/24
 */
public class QrcodeWordGenerator {

    private static final ThreadQrcode QRCODE = new ThreadQrcode();
    private final QrcodeWordConfig qrcodeConfig;

    public QrcodeWordGenerator() {
        this(new QrcodeWordConfig());
    }

    public QrcodeWordGenerator(QrcodeWordConfig qrcodeConfig) {
        this.qrcodeConfig = qrcodeConfig;
    }

    /**
     * 生成带文字二维码
     * @param content 二维码内容
     * @param words 文本内容
     * @return
     * @version 1.0  by wuhao at 2020/3/24
     */
    public QrcodeWordGenerator generate(String content, String words) throws IOException {
        BufferedImage image = new SimpleQrcodeGenerator(qrcodeConfig).generate(content).getImage();
        BufferedImage outImage = insertWords(image, words);
        QRCODE.setImage(outImage);
        return this;
    }

    public boolean toFile(String pathname) throws IOException {
        boolean var2;
        try {
            var2 = ImageIO.write(QRCODE.getImage(), "PNG", new File(pathname));
        } finally {
            this.clear();
        }

        return var2;
    }

    public boolean toStream(OutputStream output) throws IOException {
        boolean var2;
        try {
            var2 = ImageIO.write(QRCODE.getImage(), "PNG", output);
        } finally {
            this.clear();
        }

        return var2;
    }

    public void clear() {
        QRCODE.remove();
    }

    /**
     * 插入文字
     */
    public BufferedImage insertWords(BufferedImage codeImage, String words){
        //创建一个带透明色的BufferedImage对象
        int imageWidth = codeImage.getWidth();
        int imageHeight = codeImage.getHeight() + qrcodeConfig.getWordHeight();

        BufferedImage outImage = new BufferedImage(imageWidth , imageHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D outg = outImage.createGraphics();
        //设置背景色为白色
        outg.setBackground(Color.WHITE);
        outg.fillRect(0,0,imageWidth,imageHeight);
        setGraphics2D(outg);

        // 画二维码到新的面板
        outg.drawImage(codeImage, 0, 0, codeImage.getWidth(), codeImage.getHeight(), null);
        // 画文字到新的面板
        outg.setColor(qrcodeConfig.getWordColor());
        // 字体、字型、字号
        outg.setFont(new Font(qrcodeConfig.getWordFontFamily(), Font.PLAIN, qrcodeConfig.getWordFontSize()));
        //文字长度
        int strWidth = outg.getFontMetrics().stringWidth(words);
        //总长度减去文字长度的一半  （居中显示）
        int wordStartX=( codeImage.getWidth() - strWidth) / 2;
        //height + (outImage.getHeight() - height) / 2 + 12
        int wordStartY= codeImage.getHeight() +10;
        // 画文字
        outg.drawString(words, wordStartX, wordStartY);
        outg.dispose();
        outImage.flush();

        return outImage;
    }

    /**
     * 设置 Graphics2D 属性  （抗锯齿）
     * @param graphics2D
     */
    private static void setGraphics2D(Graphics2D graphics2D){
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
        Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
        graphics2D.setStroke(s);
    }

    public static void main(String[] args) throws IOException {
        QrcodeWordConfig config = (QrcodeWordConfig) new QrcodeWordConfig()
                .setBorderSize(2)
                .setPadding(10)
                .setMasterColor("#778899")
                .setLogoBorderColor("#B0C4DE")
                .setCodeEyesPointColor("#BC8F8F");
                // .setCodeEyesFormat(QreyesFormat.DR2_BORDER_C_POINT);

        new QrcodeWordGenerator(config).generate("haajdslfjsldfjlasdjflasdjflasdjfladsjlfjasdlfjlasdjfladsjfladsjlfjasdlfjh", "PDSSSSSS110000").toFile("D:\\a.png");
    }
}
